package com.ruoyi.thridApi.controller;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.common.core.domain.NewAjaxResult;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.config.WebSocketServer;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.domain.vo.*;
import com.ruoyi.system.service.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@RestController
@RequestMapping("/lockControl")
public class ThridInterController {
    private static final Logger logger = LoggerFactory.getLogger(ThridInterController.class);


    @Autowired
    IPCabinetService pcabinetService;
    @Autowired
    IPRecordService recordService;
    @Autowired
    ISysUserService sysUserService;
    @Autowired
    IPTaskService taskService;
    @Autowired
    WebSocketServer webSocketServer;
    @Autowired
    private IPProductService productService;
    @Autowired
    private IPKeyRecordService keyRecordService;

    @Anonymous
    @PostMapping("/regisiter")
    public NewAjaxResult regisiter(@RequestBody DeviceRegisterRequest lockControlVo)
    {
        return NewAjaxResult.success(pcabinetService.regisiter(lockControlVo));
    }
    @Anonymous
    @PostMapping("/heartbeat")
    public NewAjaxResult heartbeat(@RequestBody HeartbeatRequest lockControlVo) {

        logger.info("设备发来心跳信息{}", lockControlVo);
        // 查询设备是否存在
        QueryWrapper<PCabinet> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("code", lockControlVo.getSid());
        PCabinet device = pcabinetService.getOne(queryWrapper);

        if (device == null) {
            return NewAjaxResult.error("未找到对应的设备", "");
        }

        // 构建响应数据
        Map<String, Object> bizContent = new HashMap<>();

        // 处理时间同步逻辑
        if (shouldSyncTime(lockControlVo.getTimeStamp())) {
            logger.info("时间进行同步");
            String serverTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd HH:mm:ss"));
            bizContent.put("timeStamp", serverTime);
        }

        bizContent.put("DevName", device.getCabinetName());
        logger.info("心跳响应内容:{}", bizContent);
        return NewAjaxResult.success(bizContent);
    }

    /**
     * 上传记录
     * @param recodeVo
     * @return
     */
    @Anonymous
    @PostMapping("/record")
    public NewAjaxResult record(@RequestBody RecordRequest recodeVo) {
        logger.info("上传记录{}", recodeVo);
        PRecord pRecord=new PRecord();
        pRecord.setSid(recodeVo.getSid());
        pRecord.setDevId(recodeVo.getDevId());
        pRecord.setUserNo(recodeVo.getUserNo());
        pRecord.setDyPass(recodeVo.getDyPass());
        pRecord.setRealPic(recodeVo.getRealPic());
        if(StringUtils.isNotBlank(recodeVo.getRegTime())){
            pRecord.setRegTime(DateUtils.dateTime("yyyyMMdd HH:mm:ss",recodeVo.getRegTime()));
        }
        recordService.save(pRecord);
        return NewAjaxResult.success();
    }


    @Anonymous
    @PostMapping("/uploadUser")
    public NewAjaxResult uploadUser(@RequestBody UploadUserRequest userInfoVo) {
        // 1. 通过 uno 查询用户
        logger.info("uploadUser接收参数{}",userInfoVo);
        sysUserService.newInsertUser(userInfoVo);
        return NewAjaxResult.success();
    }

    @Anonymous
    @PostMapping("/dyPassCheck")
    public NewAjaxResult dyPassCheck(@RequestBody DyPassCheckRequest passCheckVo) {
        logger.info("密码验证{}", passCheckVo);
        QueryWrapper<PTask> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("sid", passCheckVo.getSid());
        queryWrapper.eq("status", "0");
        PTask task = taskService.getOne(queryWrapper);

        if (task == null) {
            logger.warn("密码验证失败：任务不存在，sid={}", passCheckVo.getSid());
            return NewAjaxResult.error("任务不存在或已处理");
        }


        task.setStatus("1");

        boolean updateSuccess = taskService.updateById(task);
        if (!updateSuccess) {
            logger.error("密码验证失败：更新任务状态失败，sid={}", passCheckVo.getSid());
            return NewAjaxResult.error("系统繁忙，请稍后再试");
        }


        QueryWrapper<PTask> queryWrappers = new QueryWrapper<>();
        queryWrappers.eq("status","0");
        Map<String, Object> jsonResult = new HashMap<>();
        jsonResult.put("dypass", taskService.list(queryWrapper));
        webSocketServer.sendInfo("1", JSONUtil.toJsonStr(jsonResult));

        logger.info("密码验证通过：sid={}，pass={}",passCheckVo.getSid(),task.getDyPass());
        return NewAjaxResult.success();
    }


    @Anonymous
    @PostMapping("/keyAllState")
    public NewAjaxResult keyAllState(@RequestBody KeysStateRequest keysStateRequest) {
        logger.info("多个钥匙状态变更通知{}", keysStateRequest);
        QueryWrapper<PProduct> queryWrappe = new QueryWrapper<>();
        queryWrappe.eq("cabinet_code", keysStateRequest.getSid());
        List<PProduct> productList = productService.list(queryWrappe);

        if (CollectionUtils.isEmpty(productList)) {
            logger.warn("多个钥匙状态变更失败：，sid={},list={}",keysStateRequest.getSid(),keysStateRequest.getKeys());
            return NewAjaxResult.error("记录不存在");
        }

        Map<String, KeyStateVo> keyStateMap = keysStateRequest.getKeys().stream()
                .collect(Collectors.toMap(
                        KeyStateVo::getKeyNo,
                        KeyStateVo ->KeyStateVo,
                        (existing, replacement) -> replacement  // 处理重复keyNo，保留后者
                ));

        List<PProduct> updateList = new ArrayList<>();
        for (PProduct product : productList) {
            String boxNoStr = String.valueOf(product.getBoxNo());
            // 从Map中快速匹配keyNo，避免内层循环
            if (keyStateMap.containsKey(boxNoStr)) {
                KeyStateVo keyStateVo = keyStateMap.get(boxNoStr);
                product.setOutboundFlag(String.valueOf(keyStateVo.getState()));
                product.setKeyId(keyStateVo.getKeyId());
                product.setErrorFlag(keyStateVo.getError());
                updateList.add(product);
            }
        }
        if (!updateList.isEmpty()) {
            boolean updateSuccess = productService.updateBatchById(updateList);
            if (!updateSuccess) {
                logger.error("多个钥匙状态批量更新失败：sid={}", keysStateRequest.getSid());
                // 事务会自动回滚
                return NewAjaxResult.error("系统繁忙，请稍后再试");
            }
        }

        Map<String, Object> jsonResult = new HashMap<>();
        jsonResult.put("keyState", productService.list(queryWrappe));
        webSocketServer.sendInfo("1", JSONUtil.toJsonStr(jsonResult));

        logger.info("多个钥匙状态变更通过：sid={},list={}",keysStateRequest.getSid(),keysStateRequest.getKeys());
        return NewAjaxResult.success();
    }

    @Anonymous
    @PostMapping("/keyState")
    public NewAjaxResult keyState(@RequestBody KeyStateRequest keyStateRequestVo) {

        logger.info("钥匙存取记录添加:{}", keyStateRequestVo);
        PKeyRecord pKeyRecord = new PKeyRecord();
        pKeyRecord.setSid(keyStateRequestVo.getSid());
        pKeyRecord.setKeyNo(keyStateRequestVo.getKeyNo());
        pKeyRecord.setRegTime(DateUtils.dateTime("yyyyMMdd HH:mm:ss",keyStateRequestVo.getRegTime()));
        pKeyRecord.setOptType(keyStateRequestVo.getOptType());
        pKeyRecord.setDevRecId(keyStateRequestVo.getDevRecId());
        keyRecordService.save(pKeyRecord);
        return NewAjaxResult.success();
    }
//    @Anonymous
//    @PostMapping("/actionResp")
//    public NewAjaxResult actionResp(@RequestBody ActionRespRequest passCheckVo) {
//        PTask task = taskService.selectPTaskByAId(passCheckVo.getActionID());
//        if (task == null) {
//            return NewAjaxResult.error("事件不存在","");
//        }
//        Map<String, String> bizContent = new HashMap<>();
//        bizContent.put("resp",task.getStatus());
//        return NewAjaxResult.success(bizContent);
//    }

    // 判断是否需要同步时间（示例实现）
    private boolean shouldSyncTime(String deviceTime) {
        if (StringUtils.isEmpty(deviceTime)) {
            return false;
        }

        try {
            // 解析设备时间
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd HH:mm:ss");
            LocalDateTime deviceDateTime = LocalDateTime.parse(deviceTime, formatter);

            // 计算与服务器时间的差值（示例：超过5分钟则需要同步）
            LocalDateTime serverDateTime = LocalDateTime.now();
            Duration duration = Duration.between(deviceDateTime, serverDateTime);

            return Math.abs(duration.toMinutes()) > 5;
        } catch (Exception e) {
            logger.error("解析设备时间失败: {}", deviceTime, e);
            return false;
        }
    }

}
